package com.superb.allocation.service.oss.impl;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.VoidResult;
import com.superb.allocation.service.oss.UploadService;
import com.superb.common.core.enums.SuperbCode;
import com.superb.common.core.exception.SuperbException;
import com.superb.common.utils.HeardersUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.UUID;

/**
 * @Author: ajie
 * @CreateTime: 2024-07-04 17:00
 */
public class UploadServiceImpl implements UploadService {
    
    private final OSS client;
    private final String bucket;
    private final String dir;

    private boolean isCover = true;

    public UploadServiceImpl(OSS client) {
        this.client = client;
        this.bucket = HeardersUtils.getHeader("bucket", () -> "zlgyl");
        this.dir = HeardersUtils.getHeader("dir", () -> "default");
        String cover = HeardersUtils.getHeader("isCover", () -> "true");
        if (!"true".equals(cover)) {
            this.isCover = false;
        }
    }

    @Override
    public String upload(byte[] bytes, ObjectMetadata meta, String filename) {
        try {
            String objectName = this.getFilename(filename);
            this.exists(objectName);
            this.client.putObject(this.bucket, objectName, new ByteArrayInputStream(bytes), meta);
            return objectName;
        } catch (OSSException oe) {
            throw new SuperbException(SuperbCode.ALIYUN_OSS_UPLOAD, oe.getMessage());
        } catch (ClientException ce) {
            throw new SuperbException(SuperbCode.ALIYUN_OSS_CLIENT, ce.getMessage());
        } finally {
            this.client.shutdown();
        }
    }

    @Override
    public String upload(String url, ObjectMetadata meta, String filename) {
        try {
            String objectName = this.getFilename(filename);
            this.exists(objectName);
            this.client.putObject(this.bucket, objectName, new URL(url).openStream(), meta);
            return objectName;
        } catch (OSSException oe) {
            throw new SuperbException(SuperbCode.ALIYUN_OSS_UPLOAD, oe.getMessage());
        } catch (ClientException ce) {
            throw new SuperbException(SuperbCode.ALIYUN_OSS_CLIENT, ce.getMessage());
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            this.client.shutdown();
        }
    }

    /**
     * 检验文件是否存在
     * @param objectName
     */
    private void exists(String objectName) {
        if (this.client.doesObjectExist(this.bucket, objectName)) {
            if (!this.isCover) {
                throw new SuperbException(SuperbCode.ALIYUN_OSS_REPEAT, objectName);
            }
        }
    }
    
    @Override
    public String upload(InputStream inputStream, ObjectMetadata meta, String filename) {
        try {
            String objectName = this.getFilename(filename);
            this.exists(objectName);
            this.client.putObject(this.bucket, objectName, inputStream, meta);
            return objectName;
        } catch (OSSException oe) {
            throw new SuperbException(SuperbCode.ALIYUN_OSS_UPLOAD, oe.getMessage());
        } catch (ClientException ce) {
            throw new SuperbException(SuperbCode.ALIYUN_OSS_CLIENT, ce.getMessage());
        } finally {
            this.client.shutdown();
        }
    }

    @Override
    public String upload(File file, ObjectMetadata meta, String filename) {
        try {
            String objectName = this.getFilename(filename);
            this.exists(objectName);
            this.client.putObject(this.bucket, objectName, file, meta);
            return objectName;
        } catch (OSSException oe) {
            throw new SuperbException(SuperbCode.ALIYUN_OSS_UPLOAD, oe.getMessage());
        } catch (ClientException ce) {
            throw new SuperbException(SuperbCode.ALIYUN_OSS_CLIENT, ce.getMessage());
        } finally {
            this.client.shutdown();
        }
    }

    @Override
    public boolean delete(String key) {
        try {
            VoidResult result = this.client.deleteObject(this.bucket, key);
            return result != null && result.getResponse().isSuccessful();
        } catch (OSSException oe) {
            throw new SuperbException(SuperbCode.ALIYUN_OSS_UPLOAD, oe.getMessage());
        } catch (ClientException ce) {
            throw new SuperbException(SuperbCode.ALIYUN_OSS_CLIENT, ce.getMessage());
        } finally {
            this.client.shutdown();
        }
    }

    /**
     * 获取文件名
     * @param filename 原始文件名
     * @return
     */
    private String getFilename(String filename) {
        String starFilename = dir + "/" + DateFormatUtils.format(new Date(), "yyyy-MM-dd") + "/";
        if (this.isCover) {
            String suffix = filename.substring(filename.lastIndexOf("."));
            return starFilename + UUID.randomUUID().toString().replace("-", "") + suffix;
        }
        return starFilename + filename;
    }
}
